package com.ffalcon.mercury.android.sdk.demo;

import android.os.Handler;
import android.os.Looper;
import android.os.Message;
import android.util.Log;

import androidx.annotation.NonNull;

import java.io.BufferedReader;
import java.io.IOException;
import java.io.InputStreamReader;
import java.io.PrintWriter;
import java.net.Socket;
import java.util.concurrent.Executors;
import java.util.concurrent.ScheduledExecutorService;
import java.util.concurrent.TimeUnit;


public class SocketClient {
    private static final String TAG = "SocketClient";
    private static String SERVER_IP = "";
    private static final int SERVER_PORT = 15139;
    private static final long HEARTBEAT_INTERVAL = 5000; // 5秒
    private static final long RECONNECT_DELAY = 5000; // 3秒

    // 初始参数
    private static String INIT_PARAMS = "";

    private Socket mSocket;
    private PrintWriter mWriter;
    private BufferedReader mReader;
    private boolean isConnected = false;
    private boolean isReady = false; // 标记是否收到READY响应
    private ScheduledExecutorService mScheduler;
    private HeartbeatListener mListener;
    private Handler mMainHandler;

    public interface HeartbeatListener {
        void onConnected();

        void onDisconnected();

        void onHeartbeatSuccess();

        void onHeartbeatFailed();

        void onReceiveMessage(String message);

        void onReady(); // 新增：收到READY响应回调


    }

    public SocketClient(HeartbeatListener listener, String ip, String taskId) {
        this.mListener = listener;
        INIT_PARAMS = "taskId=" + taskId + "&sign=rtmpCameraUrl";
        SERVER_IP = ip;

        Log.e(TAG, "初始化 INIT_PARAMS：" + INIT_PARAMS);
        Log.e(TAG, "初始化 SERVER_IP：" + SERVER_IP);



        this.mMainHandler = new Handler(Looper.getMainLooper()) {
            @Override
            public void handleMessage(@NonNull Message msg) {
                switch (msg.what) {
                    case 0:
                        mListener.onConnected();
                        break;
                    case 1:
                        mListener.onDisconnected();
                        break;
                    case 2:
                        mListener.onHeartbeatSuccess();
                        break;
                    case 3:
                        mListener.onHeartbeatFailed();
                        break;
                    case 4:
                        String msgStr = (String) msg.obj;
                        mListener.onReceiveMessage(msgStr);
                        break;
                    case 5: // 新增：收到READY
                        mListener.onReady();
                        break;
                }
            }
        };
    }

    public void start() {


        new Thread(this::connect).start();
    }

    private void connect() {
        try {
            if (mSocket != null && !mSocket.isClosed()) {
                mSocket.close();
            }
            mSocket = new Socket(SERVER_IP, SERVER_PORT);
            mWriter = new PrintWriter(mSocket.getOutputStream(), true);
            mReader = new BufferedReader(new InputStreamReader(mSocket.getInputStream()));
            isConnected = true;
            isReady = false; // 重置状态
            Log.d(TAG, "连接服务器成功");
            mMainHandler.sendEmptyMessage(0);

            // 连接成功后立即发送初始参数
            sendInitialParams();

            // 启动接收消息线程（处理READY响应和后续消息）
            startReceiveThread();

        } catch (IOException e) {
            Log.e(TAG, "连接服务器失败：" + e.getMessage());
            isConnected = false;
            mMainHandler.sendEmptyMessage(1);
            scheduleReconnect();
        }
    }

    // 发送初始参数
    private void sendInitialParams() {
        if (isConnected && mWriter != null) {
            new Thread(() -> {
                try {
                    Log.d(TAG, "发送初始参数：" + INIT_PARAMS);
                    mWriter.println(INIT_PARAMS);
                } catch (Exception e) {
                    Log.e(TAG, "初始参数发送失败：" + e.getMessage());
                    disconnect(); // 发送失败则断开重连
                }
            }).start();
        }
    }

    private void startReceiveThread() {
        new Thread(() -> {
            String message;
            try {
                while (isConnected && (message = mReader.readLine()) != null) {
                    Log.d(TAG, "收到消息：" + message);

                    // 首次收到READY后启动心跳
                    if (!isReady && "READY".equals(message)) {
                        isReady = true;
                        mMainHandler.sendEmptyMessage(5); // 通知UI已就绪
                        startHeartbeat(); // 启动心跳机制
                    }
                    // 已就绪状态下处理心跳响应和业务消息
                    else if (isReady) {
                        if ("HEARTBEAT_ACK".equals(message)) {
                            mMainHandler.sendEmptyMessage(2);
                        } else {
                            Message msg = mMainHandler.obtainMessage(4);
                            msg.obj = message;
                            mMainHandler.sendMessage(msg);
                        }
                    }
                    // 未就绪状态下收到其他消息（可能是错误）
                    else {
                        Log.e(TAG, "未收到READY，却收到其他消息：" + message);
                        disconnect(); // 流程异常，断开重连
                    }
                }
            } catch (IOException e) {
                Log.e(TAG, "接收消息异常：" + e.getMessage());
            }
            disconnect();
        }).start();
    }

    // 启动心跳（仅在收到READY后调用）
    private void startHeartbeat() {
        if (mScheduler != null && !mScheduler.isShutdown()) {
            mScheduler.shutdown();
        }
        mScheduler = Executors.newSingleThreadScheduledExecutor();
        // 使用更安全的scheduleWithFixedDelay
        mScheduler.scheduleWithFixedDelay(() -> {
            if (isConnected && isReady && mWriter != null) {
                try {
                    mWriter.println("STREAM_HEARTBEAT");
                    Log.d(TAG, "发送心跳包");
                } catch (Exception e) {
                    Log.e(TAG, "心跳发送失败：" + e.getMessage());
                    mMainHandler.sendEmptyMessage(3);
                    disconnect();
                }
            }
        }, 0, HEARTBEAT_INTERVAL, TimeUnit.MILLISECONDS);
    }

    // 断开连接（重置状态）
    public void disconnect() {
        isConnected = false;
        isReady = false; // 重置就绪状态
        if (mWriter != null) {
            mWriter.close();
            mWriter = null;
        }
        if (mReader != null) {
            try {
                mReader.close();
            } catch (IOException e) {
                e.printStackTrace();
            }
            mReader = null;
        }
        if (mSocket != null) {
            try {
                mSocket.close();
            } catch (IOException e) {
                e.printStackTrace();
            }
            mSocket = null;
        }
        if (mScheduler != null) {
            mScheduler.shutdown();
            mScheduler = null;
        }
        Log.d(TAG, "断开连接");
        mMainHandler.sendEmptyMessage(1);
        scheduleReconnect();
    }

    // 断开连接（重置状态）
    public void stop() {
        isConnected = false;
        isReady = false; // 重置就绪状态
        if (mWriter != null) {
            mWriter.close();
            mWriter = null;
        }
        if (mReader != null) {
            try {
                mReader.close();
            } catch (IOException e) {
                e.printStackTrace();
            }
            mReader = null;
        }
        if (mSocket != null) {
            try {
                mSocket.close();
            } catch (IOException e) {
                e.printStackTrace();
            }
            mSocket = null;
        }
        if (mScheduler != null) {
            mScheduler.shutdown();
            mScheduler = null;
        }
        Log.d(TAG, "断开连接");

    }
    private void scheduleReconnect() {
        if (!isConnected) {
            new Thread(() -> {
                try {
                    Thread.sleep(RECONNECT_DELAY);
                    connect();
                } catch (InterruptedException e) {
                    e.printStackTrace();
                }
            }).start();
        }
    }

    public void sendMessage(String message) {
        if (isConnected && isReady && mWriter != null) {
            new Thread(() -> mWriter.println(message)).start();
        }
    }
}
